#ifndef PARAL_PY_H
#define PARAL_PY_H

#include <string>
#include <stdio.h>
#include <assert.h>
#include <vector>
#include <map>
#include <iostream>
#include <fstream>
#include <stack>
#include <stdio.h>

// 标识符，
enum Token
{
	tok_eof = -1,

	// commands
	tok_def = -2,
	// tok_extern = -3,

	// primary
	tok_identifier = -4,

	// 函数的类型
	tok_seq_comm_assoca_def_type = -5,
	tok_seq_def_type = -6,
	tok_input_central_paral_type = -7,
	tok_iter_central_paral_type = -8,

	// 占位符
	tok_place_holder = -9,

	// 统计缩进
	tok_tab = -10,

	// 数字类型
	tok_double = -11,
	tok_int = -12,

	// 对于保留字
	tok_python_remain = -13
};

// 现在只有函数类型
struct function_table_item
{
	int function_type;

	// 函数开始的位置
	int function_begin_line;
	// 函数结束的位置
	int function_end_line;
};

// 并行转化的预处理得到的一系列数据
struct pre_process_report{
	bool can_trans;
	// 使用的二元操作符
	std::string op_str;
};

struct paral_py_context
{
	std::string identifier_str; // 获取到的标识符

	// 当获取到数字的时候，使用一个变量来存储数字的大小
	double double_num_val;
	long long_num_val;

	// 当读到换行时，使用一个变量来记录缩进次数
	int tab_size;

	// 把文件全部读出来，放到一个字符串里面
	FILE *fd;

	// 当前行号
	int line_num;

	// 当前分析的文件名
	std::string file_name;

	// 使用一个数组来存储保留字
	std::vector<std::string> remain_str_arr;

	// 使用一个数组来存储
	std::vector<std::string> import_code_str_arr;

	// 设计一个表，这个表的key是函数名称，value是函数的基本信息
	std::map<std::string, struct function_table_item> fun_table;
};

void init_paral_py_context(struct paral_py_context *ctx, const char *filename);

int get_tok(struct paral_py_context *ctx);

char get_char(struct paral_py_context *ctx);

void print_token_type(int type);

// 针对变量、tab、两种类型的数字，
void print_current_token(struct paral_py_context *ctx, int type);

void print_function_item(struct function_table_item *item);

void print_function_table(struct paral_py_context *ctx);

// 向函数表中加入一个元素
void add_item_to_function_table(struct paral_py_context *ctx, std::string fun_name, int type,
								int start_line, int end_line);

void scan_all_function(struct paral_py_context *ctx);

void print_import_code_arr(struct paral_py_context* ctx);

std::string get_code_by_line(std::string file_name, int start_line, int end_line);

std::string trans_seq_to_def(struct paral_py_context* ctx, std::string seq_fun_name);

struct pre_process_report input_paral_pre_analysis(struct paral_py_context* ctx,
                                                   std::string function_name);

std::string input_paral_translate_to_MR_map(struct paral_py_context* ctx, std::string function_name);
// 将代码翻译成
std::string input_paral_translate_to_local_seq(struct paral_py_context* ctx, std::string function_name);

std::string get_key_str_of_result(std::string result_str);

// 针对一个函数生成map文件的脚本
void build_mapper_reducer_file(struct paral_py_context* ctx, std::vector<std::string> seqs, std::string function_name);
void build_reduce_file(struct paral_py_context* ctx, std::string function_name, struct pre_process_report report);

// 针对一个函数生成本地串行循环的python脚本，复用map代码即可，不需要预处理。
void build_local_seq_file(struct paral_py_context* ctx, std::vector<std::string> seqs, std::string function_name);

// 直接生成一个报告，通过分析查看当前并行算法适合的语言
std::string build_pre_analysis_report(struct paral_py_context* ctx, std::vector<std::string> seqs, std::string function_name);

#endif
